<template>
  <div id="container">
    <!-- 上传文件/导出文件 -->
    <div class="flex">
      <n-upload :default-upload="false" :max="1" accept=".json" @change="handleUploadFileChange">
        <n-button>上传文件</n-button>
      </n-upload>
      <!-- 导出按钮 -->
      <n-dropdown :options="dropdownOptions" :show-arrow="true" v-on:select="handleDownloadSelect">
        <n-button type="primary">导出文件</n-button>
      </n-dropdown>
    </div>

    <!-- 分割线 -->
    <n-divider />
    <!-- 上传文件后 -->
    <div ref="vtable" class="vtable"></div>
  </div>
</template>

<script lang="ts" setup>
import { UploadFileInfo } from "naive-ui";
import { useConfigStore } from "@renderer/store/config";
import * as VTable from "@visactor/vtable";
import * as VTablePlugins from "@visactor/vtable-plugins";

// 全局配置
const useConfig = useConfigStore();
// 消息提示
const message = useMessage();

// 上传的文件
const uploadFile = ref<File | null>(null);
// 上传的数据
const uploadData = ref<{ key: string; value: any }[]>([]);
// 文件名
const fileName = ref<string>("");
// 表格的列
const columns = ref<{ field: string; title: string; width: "auto" }[]>([]);
// 表格元素
const vtableRef = useTemplateRef("vtable");
// 表格实例
const tableInstance = ref<VTable.ListTable>();
// 表格宽度
const containerWidth = computed(() => {
  return useConfig.collapsed ? "72px" : "224px";
});
// 下拉菜单选项
const dropdownOptions = [
  {
    key: "exportExcel",
    label: "导出Excel",
  },
  {
    key: "exportCsv",
    label: "导出CSV",
  },
];

// 上传文件事件
const handleUploadFileChange = async (options: { file: UploadFileInfo; fileList: Array<UploadFileInfo>; event?: Event }) => {
  // 文件变化检测
  if (options.fileList.length == 0) {
    uploadFile.value = null;
    uploadData.value = [];
    return;
  }

  // 格式验证
  if (options.file.type != "application/json") {
    message.error("请上传json文件");
    uploadFile.value = null;
    uploadData.value = [];
    return;
  }

  // 获取文件
  uploadFile.value = options.file.file!;
  // 文件名
  fileName.value = options.file.name.split(".")[0];

  // 读取json数据
  const arrayBuffer = await uploadFile.value.arrayBuffer();
  const json = JSON.parse(new TextDecoder().decode(arrayBuffer));

  // json中提取表格需要的数据
  json.forEach((j) => {
    // 遍历json中的每个字段
    Object.keys(j).forEach((key) => {
      // 检查字段是否已存在于列中
      if (!columns.value.find((c) => c.field === key)) {
        // 如果不存在，则添加到列中
        columns.value.push({
          field: key,
          title: key,
          width: "auto",
        });
      }
    });
  });

  // 表格导出插件
  const tableExportPlugin = new VTablePlugins.TableExportPlugin({
    exportExcelOptions: {
      downloadFile: true,
      fileName: fileName.value,
    },
    exportCsvOptions: {
      downloadFile: true,
      fileName: fileName.value,
    },
  });

  // 创建 VTable 实例
  tableInstance.value = new VTable.ListTable(vtableRef.value!, {
    records: json,
    columns: columns.value,
    widthMode: "standard",
    plugins: [tableExportPlugin],
  });
};

// 导出excel
const handleDownloadSelect = (key: string) => {
  if (!tableInstance.value) {
    message.error("请先上传文件");
    return;
  }
  switch (key) {
    case "exportExcel":
      (tableInstance.value! as any).exportToExcel();
      break;
    case "exportCsv":
      (tableInstance.value! as any).exportToCsv();
      break;
    default:
      break;
  }
};
</script>

<style lang="scss" scoped>
#container {
  width: calc(100vw - v-bind(containerWidth));

  .vtable {
    width: 100%;
    height: calc(100vh - 60px - 24px - 42px - 12px - 85px - 50px);
  }
}
</style>
